package com.macbulldev.poc.testgin.controller;

import java.util.Date;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;


import net.youngdev.util.encryption.MD5Util;

import org.apache.log4j.Logger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.macbulldev.poc.testgin.service.WebappUtils;
import com.macbulldev.poc.testgin.domain.AppRole;
import com.macbulldev.poc.testgin.domain.AppUser;
import com.macbulldev.poc.testgin.domain.EventLog;
import com.macbulldev.poc.testgin.jobs.NotifyUserStatusUpdateJob;

import edu.emory.mathcs.backport.java.util.Arrays;


@org.springframework.roo.addon.web.mvc.controller.RooWebScaffold(path = "appuser", automaticallyMaintainView = false, formBackingObject = com.macbulldev.poc.testgin.domain.AppUser.class)
@org.springframework.web.bind.annotation.RequestMapping("/appuser/**")
@org.springframework.stereotype.Controller
@Configurable

public class AppUserController {
	

	@Autowired
	@Qualifier("schedulerFactory")
	private SchedulerFactoryBean schedulerFactory;

	

	
	private static final Logger LOGGER = Logger.getLogger(AppUserController.class);
	@RequestMapping(value = "/appuser", method = RequestMethod.POST)    
    public String create(@Valid AppUser appUser, BindingResult result, ModelMap modelMap) {    
        if (appUser == null) throw new IllegalArgumentException("A appUser is required");        
        if (result.hasErrors()) {        
            modelMap.addAttribute("appUser", appUser);            
            modelMap.addAttribute("appUser_createTs_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));            
            return "appuser/create";            
        }        
        appUser.persist();        
        return "redirect:/appuser/" + appUser.getEmail();        
    }
	
	

	@RequestMapping(value = "/appuser/form", method = RequestMethod.GET)    
    public String createForm(ModelMap modelMap) {    
        modelMap.addAttribute("appUser", new AppUser());        
        modelMap.addAttribute("appUser_createTs_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));        
        return "appuser/create";        
    }
	
	@RequestMapping(value = "/appuser/unapproved/list", method = RequestMethod.GET)    
    public String getUnapprovedList(@RequestParam(value = "pageNumber", required = false) Integer page, EventLog eventLog, ModelMap modelMap) {    
        int sizeNo = 20;           
        int pageNumber= page == null ? 0 : page;
       
        modelMap.addAttribute("appusers", AppUser.findUnapproved(pageNumber*sizeNo, sizeNo));            
        Long count = AppUser.countUnapproved();
        modelMap.addAttribute("maxPageNumber", (Long)(count/sizeNo));
    return "appuser/unapproved_list";        
	}

	@RequestMapping(value = "/appuser/{email}/show", method = RequestMethod.GET)    
    public String show(@PathVariable("email") String id, ModelMap modelMap) {    
        if (id == null) throw new IllegalArgumentException("An Identifier is required");        
        modelMap.addAttribute("appUser", AppUser.getByEmail(id));        
        return "appuser/show";        
    }

	@RequestMapping(value = "/appuser", method = RequestMethod.GET)    
    public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, ModelMap modelMap) {    
        if (page != null || size != null) {        
            int sizeNo = size == null ? 10 : size.intValue();            
            modelMap.addAttribute("appusers", AppUser.findAppUserEntries(page == null ? 0 : (page.intValue() - 1) * sizeNo, sizeNo));            
            float nrOfPages = (float) AppUser.countAppUsers() / sizeNo;            
            modelMap.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));            
        } else {        
            modelMap.addAttribute("appusers", AppUser.findAllAppUsers());            
        }        
        modelMap.addAttribute("appUser_createTs_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));        
        return "appuser/list";        
    }

	@RequestMapping(value="/appuser/{email}/update",method = RequestMethod.POST)  
    @Transactional
    public String update(@PathVariable("email") String email,
    		@RequestParam(value="selectedRoles", required=false) String[] roleStrings,
    		@Valid @ModelAttribute("appUser") AppUser appUser, 
    		BindingResult result, 
    		Model model,HttpSession session) throws SchedulerException 
	{   
		AppUser sessionUser = WebappUtils.getAuthenticationObject(session);
		if (roleStrings!=null)
		{
		LOGGER.error("Selected Role"+Arrays.asList(roleStrings));
		}
		else
		{ 
			roleStrings=new String[0];
		}
		
		if (!appUser.getPassword().equals(appUser.getConfirmPassword()))
		{
			result.addError(new FieldError("appUser","confirmPassword","Password Match Failed"));
		}
    	if (!result.hasErrors()) 
    	{
    		AppUser tmp = AppUser.getByEmail(appUser.getEmail());
    		if (appUser.getPassword().startsWith(MD5Util.MD5_PREFIX))
    		{
    			appUser.setPassword(tmp.getPassword());
    		}
    		
    		int i = AppRole.deleteRolesByEmail(appUser.getEmail());
    		LOGGER.debug("Removed "+i+" roles from user "+appUser.getEmail());
    		
    		for (String roleString: roleStrings)
    		{
    			appUser.addRole(roleString);
    		}
    		tmp.detach();
    		appUser.merge();
    		LOGGER.debug(appUser.getIsApproved() +" "+ appUser.getIsEnabled() +" "+!tmp.getIsApproved() +" "+ !tmp.getIsEnabled());
    		if (appUser.getIsApproved() && appUser.getIsEnabled() && (!tmp.getIsApproved() || !tmp.getIsEnabled()))
    		{
    			notifyUser(appUser.getEmail(),Boolean.TRUE);
      		}
    		else if (tmp.getIsApproved() && tmp.getIsEnabled() && (!appUser.getIsApproved() || !appUser.getIsEnabled()) )
    		{
    			notifyUser(appUser.getEmail(),Boolean.FALSE);
    		}
    		
    		 
            EventLog log = new EventLog();
        	log.setCreateTs(new Date());
        	log.setCreateUsername(sessionUser.getEmail());

        	log.setObjectClass(AppUser.class.getSimpleName());
        	log.setOperation("User "+appUser.getEmail()+" updated");
        	log.persist();
    		
    		return "redirect:/appuser/" + appUser.getEmail()+"/show";    
    	}
    	model.addAttribute("availableRoles",AppRole.findAllUnassociatedRoles());
    	model.addAttribute("appUser",appUser);
    
    	return "appuser/update"; 
    }

	private void notifyUser(String email,Boolean enabled) throws SchedulerException  {
		
		
		Scheduler sched = schedulerFactory.getScheduler();
    	JobDetail jobDetail = new JobDetail(new Date().getTime()+Math.random()+"","default",NotifyUserStatusUpdateJob.class);
    	
    	JobDataMap jobData =  new JobDataMap();
    	jobData.put(NotifyUserStatusUpdateJob.USER_EMAIL_KEY, email);
    	jobData.put(NotifyUserStatusUpdateJob.ENABLED_BOL_KEY, enabled);
    	
    	jobDetail.setJobDataMap(jobData);
    	
    	Date now = new Date();
    	Trigger trigger = TriggerUtils.makeImmediateTrigger(0, 0);
    	trigger.setStartTime(now);
    	trigger.setName(Long.toString(now.getTime()));
    	
    	sched.scheduleJob(jobDetail, trigger);
	}
	



	@RequestMapping(value = "/appuser/{email}/update", method = RequestMethod.GET)    
    public String updateForm(@PathVariable("email") String email, ModelMap model) 
	{    
		model.addAttribute("availableRoles",AppRole.findAllUnassociatedRoles());
        if (email == null) throw new IllegalArgumentException("An Identifier is required");        
        model.addAttribute("appUser", AppUser.getByEmail(email));        
        model.addAttribute("appUser_createTs_date_format", org.joda.time.format.DateTimeFormat.patternForStyle("S-", org.springframework.context.i18n.LocaleContextHolder.getLocale()));        
        return "appuser/update";        
    }
	
	@RequestMapping(value = "/appuser/list_all_users", method = RequestMethod.GET)    
    public String renderEventLogList(@RequestParam(value = "pageNumber", required = false) Integer page, ModelMap modelMap) {    

		
		int sizeNo = 20;           
        int pageNumber= page == null ? 0 : page;
           
       // .findEventLogEntries(pageNumber*sizeNo, sizeNo)); 
        
        modelMap.addAttribute("users",AppUser.findAppUserEntries(pageNumber*sizeNo, sizeNo));             
        Long count = AppUser.countAppUsers();
        modelMap.addAttribute("maxPageNumber", (Long)(count/sizeNo));
        return "appuser/list_all_users";        
    }



	public SchedulerFactoryBean getSchedulerFactory() {
		return schedulerFactory;
	}



	public void setSchedulerFactory(SchedulerFactoryBean schedulerFactory) {
		this.schedulerFactory = schedulerFactory;
	}

	



	@RequestMapping(value = "/appuser/{email}/delete", method = RequestMethod.POST)    
    public String delete(@PathVariable("email") String id, @RequestParam(value = "pageNumber", required = false,defaultValue="0") Integer page, HttpSession session) {    
		AppUser user= WebappUtils.getAuthenticationObject(session);
        if (id == null) throw new IllegalArgumentException("An Identifier is required");        
        
        LOGGER.error("Deleting User:  "+id);
        
        
        EventLog log = new EventLog();
    	log.setCreateTs(new Date());
    	log.setCreateUsername(user.getEmail());

    	log.setObjectClass(AppUser.class.getSimpleName());
    	log.setOperation("user "+id+" deleted");
    	log.persist();
        
        
        AppUser.findAppUser(id).remove();        
        
        
        return "redirect:/appuser/list_all_users?pageNumber="+page;        
    }
	
	
	
}
